﻿using AutoMapper;
using Bot.Application.Dto;
using Bot.Domain;
using Bot.Domain.Bo;
using Bot.Domain.BotImport;
using Bot.Domain.Entities;
using Bot.Domain.Enum;
using Bot.Domain.Interfaces;
using Comm100.Framework.Domain.Repository;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

namespace Bot.Application
{
    public interface IVerifyDataManager
    {
        ErrorInfo VerifyImportBot(Guid botId, string xmlPath);
    }
    /// <summary>
    /// 公用校验部分
    /// </summary>
    public class VerifyDataManager : IVerifyDataManager
    {
        private readonly IChatbotDomainService _chatbotDomainService;
        private readonly IBackgroundJobDomainService _backgroundJobDomainService;

        public VerifyDataManager(IChatbotDomainService chatbotDomainService,
            IBackgroundJobDomainService backgroundJobDomainService)
        {
            _chatbotDomainService = chatbotDomainService;
            _backgroundJobDomainService = backgroundJobDomainService;
        }

        public ErrorInfo VerifyImportBot(Guid botId, string xmlPath)
        {
            ErrorInfo errorInfo = new ErrorInfo { Code = 1 };
            var chatbot = _chatbotDomainService.Get(botId);
            if (chatbot == null || chatbot.Id == Guid.Empty)
            {
                errorInfo = APIHelper.GetErrorMessageByCode(50004);
            }
            if (chatbot.EngineType == EnumBotType.thirdPartyBot)
            {
                errorInfo = APIHelper.GetErrorMessageByCode(50266);
            }

            return errorInfo;
        }
        
    }

    public interface IBotVerifyDataManager
    {
        ErrorInfo VerifyId(Guid id);
        ErrorInfo VerifyGetList(string include, string channel);
        ErrorInfo VerifyCreate(ChatbotCreateDto dto, bool ifDefault, string projectId);
        ErrorInfo VerifyUpdate(Guid id, ChatbotUpdateDto dto);
        ErrorInfo VerifyDelete(Guid id);
    }


    /// <summary>
    /// Bot数据有效性校验
    /// </summary>
    public class BotVerifyDataManager : IBotVerifyDataManager
    {
        private readonly IChatbotDomainService _chatbotDomainService;
        private readonly ILanguageDomainService _languageDomainService;
        private readonly IPrebuiltEntityDomainService _prebuiltEntityDomainService;
        private readonly IDialogflowDomainService _dialogflowDomainService;

        public BotVerifyDataManager(IChatbotDomainService chatbotDomainService,
            ILanguageDomainService languageDomainService,
            IPrebuiltEntityDomainService prebuiltEntityDomainService,
            IDialogflowDomainService dialogflowDomainService)
        {
            _chatbotDomainService = chatbotDomainService;
            _languageDomainService = languageDomainService;
            _prebuiltEntityDomainService = prebuiltEntityDomainService;
            _dialogflowDomainService = dialogflowDomainService;
        }

        public ErrorInfo VerifyCreate(ChatbotCreateDto dto, bool ifDefault, string projectId)
        {
            int siteId = 1000007;//token 取
            ErrorInfo errorInfo = new ErrorInfo { Code = 1 };
            if (ifDefault == true)
            {
                //检测site是否已经存在Bot
                //List<BotWithProjectIdDto> bots = _botAppService.AllBots(siteId);
                int botCount = _chatbotDomainService.GetBotCountForSite(siteId);
                if (botCount > 0)
                {
                    //return BadRequest(APIHelper.GetErrorMessageByCode(50055).ToString());
                    errorInfo.Code = 2;
                    return errorInfo;
                }
            }

            List<string> types = new List<string>() {
                EnumBotType.comm100Bot.ToString(),
                EnumBotType.thirdPartyBot.ToString(),
                EnumBotType.comm100OwnBot.ToString(),
            };
            if (!types.Contains(dto.EngineType))
            {
                return APIHelper.GetErrorMessageByCode(50263);
            }

            if (dto.EngineType.Equals(EnumBotType.comm100Bot.ToString()))
            {
                if (string.IsNullOrWhiteSpace(dto.Language))
                {
                    return APIHelper.GetErrorMessageByCode(50280);
                }

                List<Language> languageDtos = _languageDomainService.List(EnumLanguageType.Dialogflow) as List<Language>;
                List<string> ALLSupportedLanguages = languageDtos.Select(a=>a.Code).ToList();
                List<string> languages = ALLSupportedLanguages;
                if (languages == null)
                    return APIHelper.GetErrorMessageByCode(50001);
                if (!languages.Select(m => m.ToLower()).Contains(dto.Language.ToLower().Trim()))
                    return APIHelper.GetErrorMessageByCode(50217, new object[] { dto.Language });
                //code review by davy , 这里不需要验证 prebuiltEntity, 没有就没有， 不会导致创建Bot不成功
                /*
                var prebuiltEntities = _prebuiltEntityDomainService.List(dto.Language);

                if (prebuiltEntities != null && prebuiltEntities.Count() > 0)
                {
                    var prebuiltEntitiesForLanguage = prebuiltEntities.Where(o => o.Language.Contains(dto.Language.ToLower().Trim()));
                    if (prebuiltEntitiesForLanguage == null || prebuiltEntitiesForLanguage.Count() < 1)
                    {
                        return APIHelper.GetErrorMessageByCode(50048);
                    }
                }
                else
                {
                    return APIHelper.GetErrorMessageByCode(50001);
                }
                */
            }
            else if (dto.EngineType.Equals(EnumBotType.comm100OwnBot.ToString()))
            {      //2019.6.25
                if (string.IsNullOrWhiteSpace(dto.Language))
                {
                    return APIHelper.GetErrorMessageByCode(50280);
                }

                List<Language> languageDtos = _languageDomainService.List(EnumLanguageType.Chloe) as List<Language>;

                List<string> ALLSupportedLanguages = languageDtos.Select(a => a.Code).ToList();
                List<string> languages = ALLSupportedLanguages;
                if (languages == null)
                    return APIHelper.GetErrorMessageByCode(50001);
                if (!languages.Select(m => m.ToLower()).Contains(dto.Language.ToLower().Trim()))
                    return APIHelper.GetErrorMessageByCode(50217, new object[] { dto.Language });
                //code review by davy , 这里不需要验证 prebuiltEntity, 没有就没有， 不会导致创建Bot不成功
                /*
                var prebuiltEntities = _prebuiltEntityDomainService.List(dto.Language);

                if (prebuiltEntities != null && prebuiltEntities.Count() > 0)
                {
                    var prebuiltEntitiesForLanguage = prebuiltEntities.Where(o => o.Language.Contains(dto.Language.ToLower().Trim()));
                    if (prebuiltEntitiesForLanguage == null || prebuiltEntitiesForLanguage.Count() < 1)
                    {
                        return APIHelper.GetErrorMessageByCode(50048);
                    }
                }
                else
                {
                    return APIHelper.GetErrorMessageByCode(50001);
                }
                */
            }
            else
            {
                if (string.IsNullOrWhiteSpace(dto.ThirdPartyWebhook.URL))
                {
                    return APIHelper.GetErrorMessageByCode(50275);
                }
                if (dto.ThirdPartyWebhook.URL.Length > 1024)
                {
                    return APIHelper.GetErrorMessageByCode(50279);
                }
                dto.Language = "en";
            }
            if (!_chatbotDomainService.NameCheck(siteId, dto.Name))
            {
                return APIHelper.GetErrorMessageByCode(50203);
            }

            if (string.IsNullOrWhiteSpace(projectId) && !dto.EngineType.Equals(EnumBotType.thirdPartyBot.ToString()))
            {
                var bots = _chatbotDomainService.List("","");
                if (bots != null && bots.Where(w => w.EngineType != EnumBotType.thirdPartyBot).Count() >= 3 && dto.EngineType != EnumBotType.thirdPartyBot.ToString())
                    return APIHelper.GetErrorMessageByCode(50218);
            }

            if (dto.EngineType.Equals(EnumBotType.comm100Bot.ToString()))
            {
                if (string.IsNullOrWhiteSpace(projectId))
                {
                    var dialogflowDto = _dialogflowDomainService.Random(false);
                    if (dialogflowDto == null)
                        return APIHelper.GetErrorMessageByCode(50213);

                    projectId = dialogflowDto.ProjectId;
                }
                else
                {
                    if (_dialogflowDomainService.CheckInUse(projectId))
                    {
                        return APIHelper.GetErrorMessageByCode(50214,new string[] { projectId });
                    }
                }
            }

            return errorInfo;
        }

        public ErrorInfo VerifyDelete(Guid id)
        {
            ErrorInfo errorInfo = new ErrorInfo { Code = 1 };
            var chatbot = _chatbotDomainService.Get(id);
            if (chatbot == null || chatbot.Id == Guid.Empty)
            {
                errorInfo = APIHelper.GetErrorMessageByCode(50004);
            }

            return errorInfo;
        }

        public ErrorInfo VerifyId(Guid id)
        {
            ErrorInfo errorInfo = new ErrorInfo { Code = 1 };
            var chatbot = _chatbotDomainService.Get(id);
            if (chatbot == null || chatbot.Id == Guid.Empty || chatbot.IsDeleted)
            {
                errorInfo = APIHelper.GetErrorMessageByCode(50004);
            }
            //if (!string.IsNullOrEmpty(include) && !include.Equals("intent"))
            //{
            //    errorInfo = APIHelper.GetErrorMessageByCode(50283);
            //}
            return errorInfo;
        }

        public ErrorInfo VerifyGetList(string include, string channel)
        {
            throw new NotImplementedException();
        }

        public ErrorInfo VerifyUpdate(Guid id, ChatbotUpdateDto dto)
        {
            throw new NotImplementedException();
        }


        //public ErrorInfo Verify(BotDto oldBot, BotVM botVM)
        //{
        //    ErrorInfo errorInfo = null;
        //    if (oldBot.Engine.Equals(EnumBotType.thirdPartyBot.ToString()))
        //    {
        //        if (string.IsNullOrWhiteSpace(botVM.WebhookTargetUrl))
        //        {
        //            errorInfo = APIHelper.GetErrorMessageByCode(50275);
        //        }
        //        else if (botVM.WebhookTargetUrl.Length > 1280)
        //        {
        //            errorInfo = APIHelper.GetErrorMessageByCode(50279);
        //        }
        //    }
        //    else
        //    {
        //        errorInfo = ValidationBot(botVM);
        //    }

        //    if (errorInfo != null)
        //        return errorInfo;

        //    if (!oldBot.Engine.Equals(EnumBotType.thirdPartyBot.ToString()) && botVM.GreetingMessage != null)
        //    {
        //        foreach (var key in botVM.GreetingMessage.Keys)
        //        {
        //            if (botVM.GreetingMessage[key] != null && botVM.GreetingMessage.Count > 0)
        //            {
        //                if (botVM.GreetingMessage[key].Count > 10)
        //                    return APIHelper.GetErrorMessageByCode(50259);
        //                var quickResponses = botVM.GreetingMessage[key].Where(w => w.type == EnumAnswerType.quickReply);
        //                if (quickResponses != null && quickResponses.Count() > 1)
        //                    return APIHelper.GetErrorMessageByCode(51323);
        //                if (quickResponses != null && quickResponses.Count() == 1)
        //                {
        //                    Response quickResponse = quickResponses.FirstOrDefault();
        //                    botVM.GreetingMessage[key].Remove(quickResponse);
        //                    botVM.GreetingMessage[key].Add(quickResponse);
        //                }
        //                bool isSupportComplex = false;
        //                if (oldBot.GreetingMessage != null && oldBot.GreetingMessage.Any(a => a.Value != null
        //                    && a.Value.Any(ra => ra.Type == EnumAnswerType.complex)))
        //                    isSupportComplex = true;
        //                if (isSupportComplex)
        //                {
        //                    var complexResponses = botVM.GreetingMessage[key].Where(w => w.type == EnumAnswerType.complex);
        //                    if (complexResponses != null && complexResponses.Count() > 1)
        //                        return APIHelper.GetErrorMessageByCode(51345);
        //                }
        //                foreach (var response in botVM.GreetingMessage[key])
        //                {
        //                    if (response.type == EnumAnswerType.webhook)
        //                    {
        //                        return APIHelper.GetErrorMessageByCode(50257);
        //                    }
        //                    errorInfo = _verifyDataManager.ResponseValidation(response, key, oldBot.Id, oldBot.SiteId, isSupportComplex);
        //                    if (errorInfo != null)
        //                        return errorInfo;
        //                }
        //            }
        //        }
        //    }

        //    return errorInfo;
        //}
        //private ErrorInfo ValidationBot(BotVM botVM)
        //{
        //    ErrorInfo errorInfo = null;
        //    if (botVM.PossibleResponsesThreshold <= 0)
        //        errorInfo = APIHelper.GetErrorMessageByCode(50249);
        //    else if (botVM.HighConfidenceScore <= botVM.NoAnswerScore)
        //        errorInfo = APIHelper.GetErrorMessageByCode(50250);
        //    else if (botVM.HighConfidenceScore > 100 || botVM.HighConfidenceScore < 1)
        //        errorInfo = APIHelper.GetErrorMessageByCode(50251);
        //    else if (botVM.NoAnswerScore > 100 || botVM.NoAnswerScore < 0)
        //        errorInfo = APIHelper.GetErrorMessageByCode(50252);

        //    else if (string.IsNullOrWhiteSpace(botVM.AgentIsOnlineText))
        //        errorInfo = APIHelper.GetErrorMessageByCode(50276, new object[] { "AgentIsOnlineText" });
        //    else if (string.IsNullOrWhiteSpace(botVM.AgentIsOfflineText))
        //        errorInfo = APIHelper.GetErrorMessageByCode(50276, new object[] { "AgentIsOfflineText" });
        //    else if (string.IsNullOrWhiteSpace(botVM.TransferAgentMessage))
        //        errorInfo = APIHelper.GetErrorMessageByCode(50276, new object[] { "TransferAgentMessage" });
        //    else if (string.IsNullOrWhiteSpace(botVM.LeaveAMessageClickedMessage))
        //        errorInfo = APIHelper.GetErrorMessageByCode(50276, new object[] { "LeaveAMessageClickedMessage" });
        //    else if (string.IsNullOrWhiteSpace(botVM.RequestVisitorLocationMessage))
        //        errorInfo = APIHelper.GetErrorMessageByCode(50276, new object[] { "RequestVisitorLocationMessage" });
        //    else if (string.IsNullOrWhiteSpace(botVM.LocationButtonText))
        //        errorInfo = APIHelper.GetErrorMessageByCode(50276, new object[] { "LocationButtonText" });
        //    else if (string.IsNullOrWhiteSpace(botVM.SubmitButtonText))
        //        errorInfo = APIHelper.GetErrorMessageByCode(50276, new object[] { "SubmitButtonText" });
        //    else if (string.IsNullOrWhiteSpace(botVM.CancelButtonText))
        //        errorInfo = APIHelper.GetErrorMessageByCode(50276, new object[] { "CancelButtonText" });
        //    else if (string.IsNullOrWhiteSpace(botVM.ConfirmButtonText))
        //        errorInfo = APIHelper.GetErrorMessageByCode(50276, new object[] { "ConfirmButtonText" });
        //    return errorInfo;
        //}
    }

    public interface IEntityVerifyDataManager
    {

    }
    /// <summary>
    /// Entity数据有效性校验
    /// </summary>
    public class EntityVerifyDataManager : IEntityVerifyDataManager
    {

    }

    public interface IIntentVerifyDataManager
    {
        ErrorInfo VerifyGet(Guid id);
        ErrorInfo VerifyCreate(Guid botId, Dto.IntentCreateDto intentCreateDto);
        ErrorInfo VerifyUpdate(Guid id, Dto.IntentUpdateDto intentUpdateDto);
        ErrorInfo VerifyDelete(Guid id);
        ErrorInfo VerifyGetList(Guid botId, string include, Guid? categoryId, string keyword);
    }
    /// <summary>
    /// Intent数据有效性校验
    /// </summary>
    public class IntentVerifyDataManager : IIntentVerifyDataManager
    {
        private readonly IChatbotDomainService _chatbotDomainService;
        private readonly IIntentDomainService _intentDomainService;
        private readonly ICategoryDomainService _categoryDomainService;
        private readonly IEntityDomainService _entityDomainService;
        private readonly IQuickReplyDomainService _quickReplyDomainService;
        private readonly IIntentQuestionDomainService _intentQuestionDomainService;
        private readonly IIntentQuestionSelectedKeywordDomainService _intentQuestionSelectedKeywordDomainService;
        private readonly IIntentAnswerInChannelDomainService _intentAnswerInChannelDomainService;
        private readonly IAnswerInChannelAuthenticationRequestDomainService _answerInChannelAuthenticationRequestDomainService;
        private readonly IAnswerInChannelLocationRequestDomainService _answerInChannelLocationRequestDomainService;
        private readonly IAnswerInChannelFormDomainService _answerInChannelFormDomainService;
        private readonly IAnswerInChannelPromptDomainService _answerInChannelPromptDomainService;
        private readonly IResponseDomainService _responseDomainService;
        public IMapper Mapper { get; set; }

        public IntentVerifyDataManager(IChatbotDomainService chatbotDomainService,
            IIntentDomainService intentDomainService,
            ICategoryDomainService categoryDomainService,
            IEntityDomainService entityDomainService,
            IQuickReplyDomainService quickReplyDomainService,
            IIntentQuestionDomainService intentQuestionDomainService,
            IIntentQuestionSelectedKeywordDomainService intentQuestionSelectedKeywordDomainService,
            IIntentAnswerInChannelDomainService intentAnswerInChannelDomainService,
            IAnswerInChannelAuthenticationRequestDomainService answerInChannelAuthenticationRequestDomainService,
            IAnswerInChannelLocationRequestDomainService answerInChannelLocationRequestDomainService,
            IAnswerInChannelFormDomainService answerInChannelFormDomainService,
            IAnswerInChannelPromptDomainService answerInChannelPromptDomainService,
            IResponseDomainService responseDomainService)
        {
            _chatbotDomainService = chatbotDomainService;
            _intentDomainService = intentDomainService;
            _categoryDomainService = categoryDomainService;
            _entityDomainService = entityDomainService;
            _quickReplyDomainService = quickReplyDomainService;
            _intentQuestionDomainService = intentQuestionDomainService;
            _intentQuestionSelectedKeywordDomainService = intentQuestionSelectedKeywordDomainService;
            _intentAnswerInChannelDomainService = intentAnswerInChannelDomainService;
            _answerInChannelAuthenticationRequestDomainService = answerInChannelAuthenticationRequestDomainService;
            _answerInChannelLocationRequestDomainService = answerInChannelLocationRequestDomainService;
            _answerInChannelFormDomainService = answerInChannelFormDomainService;
            _answerInChannelPromptDomainService = answerInChannelPromptDomainService;
            _responseDomainService = responseDomainService;
        }

        public ErrorInfo VerifyCreate(Guid botId, IntentCreateDto intentCreateDto)
        {
            int siteId = 1000007;//从token取
            ErrorInfo errorInfo = new ErrorInfo { Code = 1 };
            var chatbot = _chatbotDomainService.Get(botId);
            if (chatbot == null || chatbot.IsDeleted)
            {
                errorInfo = APIHelper.GetErrorMessageByCode(50004);
            }
            if (chatbot.EngineType == EnumBotType.thirdPartyBot)
            {
                errorInfo = APIHelper.GetErrorMessageByCode(50266);
            }
            bool isSupportComplex = false;
            
            errorInfo = IntentValidation(intentCreateDto, botId, siteId, isSupportComplex);

            if(errorInfo == null
                || errorInfo.Code == 1)
            {
                //检测 name 重复
                if (!_intentDomainService.NameCheck(chatbot.Id, intentCreateDto.Name))
                {
                    errorInfo = APIHelper.GetErrorMessageByCode(51201);
                }
            }

            return errorInfo;
        }

        public ErrorInfo VerifyDelete(Guid id)
        {
            ErrorInfo errorInfo = new ErrorInfo { Code = 1 };
            var intent = _intentDomainService.Get(id);
            if (intent == null || intent.IsDeleted)
            {
                errorInfo = APIHelper.GetErrorMessageByCode(50004);
            }
            return errorInfo;
        }

        public ErrorInfo VerifyGet(Guid id)
        {
            ErrorInfo errorInfo = new ErrorInfo { Code = 1 };
            var intent = _intentDomainService.Get(id);
            if (intent == null || intent.IsDeleted)
            {
                errorInfo = APIHelper.GetErrorMessageByCode(50004);
            }
            return errorInfo;
        }

        public ErrorInfo VerifyUpdate(Guid id, IntentUpdateDto intentUpdateDto)
        {
            int siteId = 1000007; //Token

            ErrorInfo errorInfo = new ErrorInfo { Code = 1 };
            var intent = _intentDomainService.Get(id);
            if (intent == null || intent.IsDeleted)
            {
                errorInfo = APIHelper.GetErrorMessageByCode(50004);
            }

            //校验已经在的id 是否存在
            //questions
            if (intent.Questions != null && intent.Questions.Count > 0)
            {
                var questionExistIds = intent.Questions.Where(f => f.Id != Guid.Empty);
                if(questionExistIds!=null&& questionExistIds.Count() > 0)
                {
                    var questions = _intentQuestionDomainService.GetByIds(id, questionExistIds.Select(f => f.Id).Distinct().ToList());
                    var notExistsIds = questionExistIds.Select(f => f.Id).Except(questions.Select(f => f.Id));

                    if (notExistsIds!=null&& notExistsIds.Count()>0)
                    {
                        //存在不存在的id
                        errorInfo = APIHelper.GetErrorMessageByCode(51403, new string[] { string.Join(',', notExistsIds) });
                        return errorInfo;
                    }

                    foreach(var question in questionExistIds)
                    {
                        if(question.SelectedKeywords!=null&& question.SelectedKeywords.Any(f => f.Id != Guid.Empty))
                        {
                            var keywords = _intentQuestionSelectedKeywordDomainService.GetByQuestionId(question.Id);
                            var keywordNotExistsIds = question.SelectedKeywords.Where(f => f.Id != Guid.Empty).Select(a=>a.Id).Except(keywords.Select(a=>a.Id));
                            if (keywordNotExistsIds != null && keywordNotExistsIds.Count() > 0)
                            {
                                //存在不存在的id
                                errorInfo = APIHelper.GetErrorMessageByCode(51404, new string[] { string.Join(',', keywordNotExistsIds) });
                                return errorInfo;
                            }
                        }                  

                    }
                }
            }
            //answerInChannels
            if (intent.AnswerInChannels != null && intent.AnswerInChannels.Count > 0)
            {
                var answerInChannelExistIds = intent.AnswerInChannels.Where(f => f.Id != Guid.Empty);
                if (answerInChannelExistIds != null && answerInChannelExistIds.Count() > 0)
                {
                    var answerInChannels = _intentAnswerInChannelDomainService.GetByIntentId(id);
                    var notAnswerInChannelsExistsIds = answerInChannelExistIds.Select(a=>a.Id).Except(answerInChannels.Select(a => a.Id));
                    if(notAnswerInChannelsExistsIds!=null&& notAnswerInChannelsExistsIds.Count() > 0)
                    {
                        //存在不存在的id
                        errorInfo = APIHelper.GetErrorMessageByCode(51405, new string[] { string.Join(',', notAnswerInChannelsExistsIds) });
                        return errorInfo;
                    }

                    foreach(var answerChannel in answerInChannelExistIds)
                    {
                        //authenticationRequest
                        if(answerChannel.AuthenticationRequest!=null&& answerChannel.AuthenticationRequest.Id != Guid.Empty)
                        {
                           var answerInChannelAuthenticationRequest = _answerInChannelAuthenticationRequestDomainService.Get(answerChannel.AuthenticationRequest.Id);
                            if (answerInChannelAuthenticationRequest == null 
                                || answerInChannelAuthenticationRequest.Id != answerChannel.AuthenticationRequest.Id)
                            {
                                //存在不存在的id
                                errorInfo = APIHelper.GetErrorMessageByCode(51406, new string[] { answerChannel.AuthenticationRequest.Id.ToString() });
                                return errorInfo;
                            }
                        }

                        //locationRequest
                        if (answerChannel.LocationRequest != null && answerChannel.LocationRequest.Id != Guid.Empty)
                        {
                            var answerInChannelLocationRequest = _answerInChannelLocationRequestDomainService.Get(answerChannel.LocationRequest.Id);
                            if (answerInChannelLocationRequest == null
                                || answerInChannelLocationRequest.Id != answerChannel.LocationRequest.Id)
                            {
                                //存在不存在的id
                                errorInfo = APIHelper.GetErrorMessageByCode(51407, new string[] { answerChannel.LocationRequest.Id.ToString() });
                                return errorInfo;
                            }
                        }

                        //form
                        if (answerChannel.Form != null && answerChannel.Form.Id != Guid.Empty)
                        {
                            var form = _answerInChannelFormDomainService.Get(answerChannel.Form.Id, "fields");
                            if (form == null
                                || form.Id != answerChannel.Form.Id)
                            {
                                //存在不存在的id
                                errorInfo = APIHelper.GetErrorMessageByCode(51408, new string[] { answerChannel.Form.Id.ToString() });
                                return errorInfo;
                            }

                            //fields
                            if(answerChannel.Form.Fields!=null&& answerChannel.Form.Fields.Any(f=>f.Id != Guid.Empty))
                            {
                                var notFieldsExistsIds = answerChannel.Form.Fields.Select(a => a.Id).Except(form.Fields.Select(a => a.Id));
                                if (notFieldsExistsIds != null && notFieldsExistsIds.Count() > 0)
                                {
                                    //存在不存在的id
                                    errorInfo = APIHelper.GetErrorMessageByCode(51409, new string[] { string.Join(',', notFieldsExistsIds) });
                                    return errorInfo;
                                }
                            }
                        }

                        //prompts
                        if(answerChannel.Prompts!=null&& answerChannel.Prompts.Any(f => f.Id != Guid.Empty))
                        {
                            var prompts = _answerInChannelPromptDomainService.GetByAnswerInChannelId(answerChannel.Id);
                            var notPromptsExistsIds = answerChannel.Prompts.Where(f=>f.Id!=Guid.Empty).Select(a => a.Id).Except(prompts.Select(a => a.Id));
                            if (notPromptsExistsIds != null && notPromptsExistsIds.Count() > 0)
                            {
                                //存在不存在的id
                                errorInfo = APIHelper.GetErrorMessageByCode(51410, new string[] { string.Join(',', notPromptsExistsIds) });
                                return errorInfo;
                            }
                        }

                        //responses
                        if (answerChannel.Responses != null && answerChannel.Responses.Any(f => f.Id != Guid.Empty))
                        {
                            var responses = _responseDomainService.GetByParentId(answerChannel.Id);
                            var notResponseExistsIds = answerChannel.Responses.Where(f => f.Id != Guid.Empty).Select(a => a.Id).Except(responses.Select(a => a.Id));
                            if (notResponseExistsIds != null && notResponseExistsIds.Count() > 0)
                            {
                                //存在不存在的id
                                errorInfo = APIHelper.GetErrorMessageByCode(51411, new string[] { string.Join(',', notResponseExistsIds) });
                                return errorInfo;
                            }
                        }
                    }
                }
            }

            bool isSupportComplex = false;
            var intentCreateDto = Mapper.Map<IntentCreateDto>(intentUpdateDto);
            errorInfo = IntentValidation(intentCreateDto, Guid.Empty, siteId, isSupportComplex);

            return errorInfo;
        }

        public ErrorInfo VerifyGetList(Guid botId, string include, Guid? categoryId, string keyword)
        {
            ErrorInfo errorInfo = new ErrorInfo { Code = 1 };
            var chatbot = _chatbotDomainService.Get(botId);
            if (chatbot == null || chatbot.IsDeleted)
            {
                errorInfo = APIHelper.GetErrorMessageByCode(50004);
            }
            if (categoryId.HasValue)
            {
                var category = _categoryDomainService.Get(categoryId.Value);
                if (category == null || category.IsDeleted || category.BotId != botId)
                {
                    errorInfo = APIHelper.GetErrorMessageByCode(50004);
                }
            }
            if(!string.IsNullOrEmpty(include)&& include.Length > 2000)
            {
                errorInfo = APIHelper.GetErrorMessageByCode(50056);
            }
            if (!string.IsNullOrEmpty(keyword) && keyword.Length > 2000)
            {
                errorInfo = APIHelper.GetErrorMessageByCode(50057);
            }
            return errorInfo;
        }

        private ErrorInfo IntentValidation(IntentCreateDto intent, Guid botId, int siteId, bool isSupportComplex)
        {
            if (intent == null)
                return APIHelper.GetErrorMessageByCode(50001);
            if (intent.Questions == null || intent.Questions.Count <= 0)
                return APIHelper.GetErrorMessageByCode(51207);
            if (intent.AnswerInChannels == null || intent.AnswerInChannels.Count <= 0)
                return APIHelper.GetErrorMessageByCode(51208);
            //if (intent.AnswerInChannels.All(a => a.Value == null || a.Value.Responses == null || a.Value.Responses.Count <= 0))
            //    return APIHelper.GetErrorMessageByCode(51371);
            if (string.IsNullOrWhiteSpace(intent.Name))
                return APIHelper.GetErrorMessageByCode(51209);
            if (intent.Name.Length > 100)
                return APIHelper.GetErrorMessageByCode(51210);
            if (intent.Name.Equals("default", StringComparison.InvariantCultureIgnoreCase))
                return APIHelper.GetErrorMessageByCode(51211);
            if (intent.CategoryId == Guid.Empty)
                return APIHelper.GetErrorMessageByCode(51303);
            var categoryDto = _categoryDomainService.Get(intent.CategoryId);
            if (categoryDto == null || categoryDto.IsDeleted)
                return APIHelper.GetErrorMessageByCode(51304, new object[] { intent.CategoryId });
            //if (categoryDto.SiteId != siteId)
            //    return APIHelper.GetErrorMessageByCode(51305, new object[] { intent.CategoryId, siteId });
            if (botId!=Guid.Empty&&categoryDto.BotId != botId)
                return APIHelper.GetErrorMessageByCode(51306, new object[] { intent.CategoryId, botId });
            Dictionary<Guid, List<string>> valData = new Dictionary<Guid, List<string>>();
            string regexStr = @"^(?![0-9_-])[a-zA-Z0-9_-]{1,30}$";
            if (intent.Questions != null && intent.Questions.Count > 0)
            {
                if (intent.Questions.GroupBy(g => g.Content.Trim()).Any(a => a.Count() > 1))
                    return APIHelper.GetErrorMessageByCode(51350);
                if (intent.Questions.Count > 2000)
                    return APIHelper.GetErrorMessageByCode(51254);
                List<string> allLabels = new List<string>();
                for (int i = 0; i < intent.Questions.Count; i++)
                {
                    if (string.IsNullOrWhiteSpace(intent.Questions[i].Content)) return APIHelper.GetErrorMessageByCode(51353);
                    if (intent.Questions[i].Content.Length > 768) return APIHelper.GetErrorMessageByCode(51255);
                    if (intent.Questions[i].SelectedKeywords == null || intent.Questions[i].SelectedKeywords.Count <= 0) continue;
                    List<string> labels = new List<string>();
                    List<Tuple<int?, int?>> positions = new List<Tuple<int?, int?>>();
                    foreach (var item in intent.Questions[i].SelectedKeywords)
                    {
                        if (string.IsNullOrWhiteSpace(item.EntityLabel))
                            return APIHelper.GetErrorMessageByCode(51256);
                        if (item.EntityLabel.Length > 30)
                            return APIHelper.GetErrorMessageByCode(51257);
                        if (item.EntityLabel.Trim().EndsWith("_") || item.EntityLabel.Trim().EndsWith("-")
                            || item.EntityLabel.Trim().StartsWith("_") || item.EntityLabel.Trim().StartsWith("-") ||
                            !Regex.IsMatch(item.EntityLabel, regexStr))
                            return APIHelper.GetErrorMessageByCode(51258);
                        if (item.EntityId == Guid.Empty)
                            return APIHelper.GetErrorMessageByCode(51259);
                        var entityDto = _entityDomainService.Get(item.EntityId);
                        if (entityDto == null)
                            return APIHelper.GetErrorMessageByCode(51307, new object[] { item.EntityId });
                        //if (entityDto.SiteId != siteId)
                        //    return APIHelper.GetErrorMessageByCode(51308, new object[] { item.EntityId, siteId });
                        if (botId!=Guid.Empty&&entityDto.BotId != botId)
                            return APIHelper.GetErrorMessageByCode(51309, new object[] { item.EntityId, botId });
                        if (item.StartPosition > item.EndPosition)
                            return APIHelper.GetErrorMessageByCode(51260);
                        int length = intent.Questions[i].Content.Length;
                        if (item.StartPosition >= length)
                            return APIHelper.GetErrorMessageByCode(51335, new object[] { item.StartPosition, length });
                        if (item.EndPosition > length)
                            return APIHelper.GetErrorMessageByCode(51336, new object[] { item.EndPosition, length });
                        if (labels.Contains(item.EntityLabel))
                            return APIHelper.GetErrorMessageByCode(51327, new object[] { item.EntityLabel });
                        else
                            labels.Add(item.EntityLabel);
                        if (!allLabels.Contains(item.EntityLabel))
                        {
                            allLabels.Add(item.EntityLabel);
                        }
                        foreach (var key in valData.Keys)
                        {
                            if (valData[key].Contains(item.EntityLabel) && item.EntityId != key)
                                return APIHelper.GetErrorMessageByCode(51330, new object[] { item.EntityLabel, item.EntityId });
                        }
                        if (valData.Keys.Contains(item.EntityId))
                            valData[item.EntityId].Add(item.EntityLabel);
                        else
                            valData.Add(item.EntityId, new List<string>() { item.EntityLabel });
                        foreach (var pos in positions)
                        {
                            if (item.StartPosition >= pos.Item1 && item.StartPosition <= pos.Item2)
                                return APIHelper.GetErrorMessageByCode(51328, new object[] { item.StartPosition, pos.Item1, pos.Item2 });
                            if (item.EndPosition >= pos.Item1 && item.EndPosition <= pos.Item2)
                                return APIHelper.GetErrorMessageByCode(51329, new object[] { item.EndPosition, pos.Item1, pos.Item2 });
                        }
                        positions.Add(new Tuple<int?, int?>(item.StartPosition, item.EndPosition));
                    }
                }
                if (allLabels.Count > 20)
                    return APIHelper.GetErrorMessageByCode(51366);
            }
            //1. via prompts 时，promot数量大于0,小于等于30，长度最长为768
            //2. via form 时，字段数量大于0，entity 长度大于0，entityLabel 长度在0-30之间
            //option个数小于等于10，字段长度小于20
            //entity name  / entitylabel 只能允许输入 A-Z ,a-z ,0-9, _ - 之内的字符,长度在30以内。
            //button上的文字最长20

            foreach (var answerInChannel in intent.AnswerInChannels)
            {
                if (string.IsNullOrEmpty(answerInChannel.Channel))
                    return APIHelper.GetErrorMessageByCode(51386);

                if (answerInChannel.Channel.Length>128)
                    return APIHelper.GetErrorMessageByCode(51387);

                if (!string.IsNullOrEmpty(answerInChannel.InformationCollectionType) 
                    && !(answerInChannel.InformationCollectionType == EnumEntityCollectionType.form.ToString()
                        || answerInChannel.InformationCollectionType != EnumEntityCollectionType.prompt.ToString()))
                    return APIHelper.GetErrorMessageByCode(51261);

                if (!string.IsNullOrEmpty(answerInChannel.InformationCollectionType)
                    && answerInChannel.InformationCollectionType == EnumEntityCollectionType.prompt.ToString()
                    && (answerInChannel.Prompts == null || answerInChannel.Prompts.Count <= 0))
                    return APIHelper.GetErrorMessageByCode(51262);

                if (!string.IsNullOrEmpty(answerInChannel.InformationCollectionType)
                    && answerInChannel.InformationCollectionType == EnumEntityCollectionType.form.ToString()
                    && (answerInChannel.Form == null || answerInChannel.Form.Fields == null || answerInChannel.Form.Fields.Count <= 0))
                    return APIHelper.GetErrorMessageByCode(51263);

                if (!string.IsNullOrEmpty(answerInChannel.InformationCollectionType)
                    && answerInChannel.InformationCollectionType == EnumEntityCollectionType.form.ToString()
                    && answerInChannel.Form != null
                    && string.IsNullOrWhiteSpace(answerInChannel.Form.Message))
                    return APIHelper.GetErrorMessageByCode(51264);

                if (!string.IsNullOrEmpty(answerInChannel.InformationCollectionType)
                    && answerInChannel.InformationCollectionType == EnumEntityCollectionType.form.ToString()
                    && answerInChannel.Form != null
                    && string.IsNullOrWhiteSpace(answerInChannel.Form.Title))
                    return APIHelper.GetErrorMessageByCode(51265);

                if (!string.IsNullOrEmpty(answerInChannel.InformationCollectionType)
                    && answerInChannel.InformationCollectionType == EnumEntityCollectionType.form.ToString()
                    && answerInChannel.Form != null
                    && answerInChannel.Form.Message.Length > 1280)
                    return APIHelper.GetErrorMessageByCode(51266);

                if (!string.IsNullOrEmpty(answerInChannel.InformationCollectionType)
                    && answerInChannel.InformationCollectionType == EnumEntityCollectionType.form.ToString()
                    && answerInChannel.Form != null
                    && answerInChannel.Form.Title.Length > 20)
                    return APIHelper.GetErrorMessageByCode(51267);

                if (!string.IsNullOrEmpty(answerInChannel.InformationCollectionType)
                    && answerInChannel.InformationCollectionType == EnumEntityCollectionType.form.ToString())
                {
                    var errorInfo = ValidateEntityCollectionFormFields(answerInChannel.Form.Fields, valData, botId, siteId, regexStr);
                    if (errorInfo != null) return errorInfo;
                }
                if (!string.IsNullOrEmpty(answerInChannel.InformationCollectionType)
                    && answerInChannel.InformationCollectionType == EnumEntityCollectionType.prompt.ToString())
                {
                    var errorInfo = ValidateEntityCollectionPrompts(answerInChannel.Prompts, valData, botId, siteId, regexStr);
                    if (errorInfo != null) return errorInfo;
                }

                ErrorInfo error = AnswerValidation(answerInChannel, botId, siteId, isSupportComplex);
                if (error != null) return error;
            }            

            //List<string> channels = new List<string>();
            //foreach (var key in intent.Answer.Keys)
            //{
            //    string channel = key.ToLower();
            //    if (channels.Contains(channel))
            //        return APIHelper.GetErrorMessageByCode(51339);
            //    channels.Add(channel);
            //    if (channel == ConstChannelType.Default || channel == ConstChannelType.Livechat || channel == ConstChannelType.Facebook || channel == ConstChannelType.Twitter)
            //        continue;
            //    return APIHelper.GetErrorMessageByCode(51340);
            //}
            //if(!channels.Contains(ConstChannelType.Default))
            //    return APIHelper.GetErrorMessageByCode(51355);
            //foreach (var key in intent.Answer.Keys)
            //{
            //    //if (key.Equals(ConstChannelType.Default, StringComparison.InvariantCultureIgnoreCase))
            //    //{
            //    //    if (intent.Answer[key].Responses == null || intent.Answer[key].Responses.Count <= 0)
            //    //        return APIHelper.GetErrorMessageByCode(51355);
            //    //}
            //    if (intent.Answer[key].Responses == null || intent.Answer[key].Responses.Count <= 0)
            //        continue;
            //    //return APIHelper.GetErrorMessageByCode(51355);
            //    Bot.Infrastructure.ErrorInfo error = AnswerValidation(intent.Answer[key], key, botId, siteId, isSupportComplex);
            //    if (error != null) return error;
            //}
            return null;
        }
        private ErrorInfo ValidateEntityCollectionFormFields(List<AnswerInChannelFormFieldCreateDto> fields,
            Dictionary<Guid, List<string>> labels, Guid botId, int siteId, string regexStr)
        {
            List<string> existLabel = new List<string>();
            List<string> fieldTypes = new List<string>();
            fieldTypes.Add(Domain.Enum.EnumFieldType.text.ToString());
            fieldTypes.Add(Domain.Enum.EnumFieldType.textArea.ToString());
            fieldTypes.Add(Domain.Enum.EnumFieldType.radio.ToString());
            fieldTypes.Add(Domain.Enum.EnumFieldType.checkBox.ToString());
            fieldTypes.Add(Domain.Enum.EnumFieldType.checkBoxList.ToString());
            fieldTypes.Add(Domain.Enum.EnumFieldType.dropDownList.ToString());
            foreach (var item in fields)
            {
                //if (string.IsNullOrWhiteSpace(item.Label))
                //    return APIHelper.GetErrorMessageByCode(51268);

                if (!string.IsNullOrEmpty(item.EntityLabel))
                {
                    if (item.EntityLabel.Length > 30)
                        return APIHelper.GetErrorMessageByCode(51269);
                    if (item.EntityLabel.Trim().EndsWith("_") || item.EntityLabel.Trim().EndsWith("-")
                    || item.EntityLabel.Trim().StartsWith("_") || item.EntityLabel.Trim().StartsWith("-") ||
                    !Regex.IsMatch(item.EntityLabel, regexStr))
                        return APIHelper.GetErrorMessageByCode(51270);
                    if (string.IsNullOrEmpty(item.EntityId)
                        || !Guid.TryParse(item.EntityId,out var result) 
                        || Guid.Parse(item.EntityId) == Guid.Empty)
                        return APIHelper.GetErrorMessageByCode(51271);
                    var entityDto = _entityDomainService.Get(Guid.Parse(item.EntityId));
                    if (entityDto == null)
                        return APIHelper.GetErrorMessageByCode(51317, new object[] { item.EntityId });
                    //if (entityDto.SiteId != siteId)
                    //    return APIHelper.GetErrorMessageByCode(51318, new object[] { item.EntityId, siteId });
                    if (botId!=Guid.Empty&&entityDto.BotId != botId)
                        return APIHelper.GetErrorMessageByCode(51319, new object[] { item.EntityId, botId });
                    if (!labels.Keys.Contains(Guid.Parse(item.EntityId)))
                        return APIHelper.GetErrorMessageByCode(51331, new object[] { item.EntityId });
                    if (!labels[Guid.Parse(item.EntityId)].Contains(item.EntityLabel))
                        return APIHelper.GetErrorMessageByCode(51333, new object[] { item.EntityId, item.EntityLabel });
                    if (existLabel.Contains(item.EntityLabel))
                    {
                        return APIHelper.GetErrorMessageByCode(51338, new object[] { item.EntityLabel });
                    }
                    else
                    {
                        existLabel.Add(item.EntityLabel);
                    }
                }

                if (item.Options != null)
                {
                    if (item.Options.Count > 10)
                        return APIHelper.GetErrorMessageByCode(51272);
                    foreach (var option in item.Options)
                    {
                        if (string.IsNullOrWhiteSpace(option))
                            return APIHelper.GetErrorMessageByCode(51273);
                        if (option.Length > 100)
                            return APIHelper.GetErrorMessageByCode(51274);
                    }
                }
                if (!fieldTypes.Contains(item.Type))
                    return APIHelper.GetErrorMessageByCode(51275);
                if (string.IsNullOrWhiteSpace(item.Name))
                    return APIHelper.GetErrorMessageByCode(51276);
                if (item.Name.Length > 128)
                    return APIHelper.GetErrorMessageByCode(51277);
            }
            return null;
        }
        private ErrorInfo ValidateEntityCollectionPrompts(List<AnswerInChannelPromptCreateDto> prompts,
            Dictionary<Guid, List<string>> labels, Guid botId, int siteId, string regexStr)
        {
            List<string> existLabel = new List<string>();
            foreach (var item in prompts)
            {
                if (string.IsNullOrWhiteSpace(item.EntityLabel))
                    return APIHelper.GetErrorMessageByCode(51278);
                if (item.EntityLabel.Length > 30)
                    return APIHelper.GetErrorMessageByCode(51279);
                if (item.EntityLabel.Trim().EndsWith("_") || item.EntityLabel.Trim().EndsWith("-")
                  || item.EntityLabel.Trim().StartsWith("_") || item.EntityLabel.Trim().StartsWith("-") ||
                  !Regex.IsMatch(item.EntityLabel, regexStr))
                    return APIHelper.GetErrorMessageByCode(51280);
                if (string.IsNullOrEmpty(item.EntityId)
                   || !Guid.TryParse(item.EntityId, out var result)
                   || Guid.Parse(item.EntityId) == Guid.Empty)
                    return APIHelper.GetErrorMessageByCode(51281);
                var entityDto = _entityDomainService.Get(Guid.Parse(item.EntityId));
                if (entityDto == null)
                    return APIHelper.GetErrorMessageByCode(51320, new object[] { item.EntityId });
                //if (entityDto.SiteId != siteId)
                //    return APIHelper.GetErrorMessageByCode(51321, new object[] { item.EntityId, siteId });
                if (botId != Guid.Empty && entityDto.BotId != botId)
                    return APIHelper.GetErrorMessageByCode(51322, new object[] { item.EntityId, botId });
                if (!labels.Keys.Contains(Guid.Parse(item.EntityId)))
                    return APIHelper.GetErrorMessageByCode(51332, new object[] { item.EntityId });
                if (!labels[Guid.Parse(item.EntityId)].Contains(item.EntityLabel))
                    return APIHelper.GetErrorMessageByCode(51334, new object[] { item.EntityId, item.EntityLabel });
                if (existLabel.Contains(item.EntityLabel))
                {
                    return APIHelper.GetErrorMessageByCode(51337, new object[] { item.EntityLabel });
                }
                else
                {
                    existLabel.Add(item.EntityLabel);
                }
                if (item.Options != null)
                {
                    //2016.6.26 取消个数限制
                    //if (item.Options.Count > 10)
                    //    return APIHelper.GetErrorMessageByCode(51282);
                    foreach (var option in item.Options)
                    {
                        if (string.IsNullOrWhiteSpace(option))
                            return APIHelper.GetErrorMessageByCode(51283);
                        if (option.Length > 20)
                            return APIHelper.GetErrorMessageByCode(51284);
                    }

                    if (JsonConvert.SerializeObject(item.Options).Length > 1024)
                        return APIHelper.GetErrorMessageByCode(51365);
                }
                if (string.IsNullOrEmpty(item.Question))
                    return APIHelper.GetErrorMessageByCode(51285);
                if (item.Question.Length>768)
                    return APIHelper.GetErrorMessageByCode(51288);
                //if (item.Question.Count > 30)
                //    return APIHelper.GetErrorMessageByCode(51286);
                //foreach (var question in item.Question)
                //{
                //    if (string.IsNullOrWhiteSpace(question))
                //        return APIHelper.GetErrorMessageByCode(51287);
                //    if (question.Length > 768)
                //        return APIHelper.GetErrorMessageByCode(51288);
                //}

            }
            return null;
        }
        private ErrorInfo AnswerValidation(IntentAnswerInChannelCreateDto subItem, Guid botId, int siteId, bool isSupportComplex)
        {
            List<EnumOpenIn?> openInLst = new List<EnumOpenIn?>();
            openInLst.Add(EnumOpenIn.currentWindow);
            openInLst.Add(EnumOpenIn.newWindow);
            openInLst.Add(EnumOpenIn.sideWindow);
            //允许response为空，response为空时认为该channel不存在数据
            //response不为空时，对数据做校验
            if (subItem != null && subItem.Responses != null && subItem.Responses.Count > 10)
                return APIHelper.GetErrorMessageByCode(51212);
            //if (subItem != null && subItem.Responses != null && subItem.Responses.Count > 0
            //   && subItem.IfNeedSignIn && subItem.AnswerSignInSettings == null)
            //    return APIHelper.GetErrorMessageByCode(51213);
            if (subItem != null
              && subItem.AuthenticationRequest != null 
              && string.IsNullOrEmpty(subItem.AuthenticationRequest.Method))
                return APIHelper.GetErrorMessageByCode(51388);
            if (subItem != null
              && subItem.AuthenticationRequest != null
              && !string.IsNullOrEmpty(subItem.AuthenticationRequest.Method)
              && !(subItem.AuthenticationRequest.Method == "SSO" 
                || subItem.AuthenticationRequest.Method == "customVariable"))
                return APIHelper.GetErrorMessageByCode(51389);
            if (subItem != null
              && subItem.AuthenticationRequest != null
              && !string.IsNullOrEmpty(subItem.AuthenticationRequest.Method)
              && subItem.AuthenticationRequest.Method == "SSO"
              && string.IsNullOrWhiteSpace(subItem.AuthenticationRequest.SignInButtonText))
                return APIHelper.GetErrorMessageByCode(51390);
            if (subItem != null
              && subItem.AuthenticationRequest != null
              && !string.IsNullOrEmpty(subItem.AuthenticationRequest.Method)
              && subItem.AuthenticationRequest.Method == "SSO"
              && string.IsNullOrWhiteSpace(subItem.AuthenticationRequest.SignInMessage))
                return APIHelper.GetErrorMessageByCode(51391);
            if (subItem != null
              && subItem.AuthenticationRequest != null
              && !string.IsNullOrEmpty(subItem.AuthenticationRequest.Method)
              && subItem.AuthenticationRequest.Method == "SSO"
              && string.IsNullOrWhiteSpace(subItem.AuthenticationRequest.SignInURL))
                return APIHelper.GetErrorMessageByCode(51392);
            if (subItem != null
              && subItem.AuthenticationRequest != null
              && !string.IsNullOrEmpty(subItem.AuthenticationRequest.Method)
              && subItem.AuthenticationRequest.Method == "customVariable"
              && string.IsNullOrWhiteSpace(subItem.AuthenticationRequest.CustomVariable))
               return APIHelper.GetErrorMessageByCode(51393);
            if (subItem != null
              && subItem.AuthenticationRequest != null
              && !string.IsNullOrEmpty(subItem.AuthenticationRequest.Method)
              && subItem.AuthenticationRequest.Method == "SSO"
              && subItem.AuthenticationRequest.SignInButtonText.Length>128)
                return APIHelper.GetErrorMessageByCode(51394);
            if (subItem != null
              && subItem.AuthenticationRequest != null
              && !string.IsNullOrEmpty(subItem.AuthenticationRequest.Method)
              && subItem.AuthenticationRequest.Method == "SSO"
              && subItem.AuthenticationRequest.SignInMessage.Length>1280)
                return APIHelper.GetErrorMessageByCode(51395);
            if (subItem != null
              && subItem.AuthenticationRequest != null
              && !string.IsNullOrEmpty(subItem.AuthenticationRequest.Method)
              && subItem.AuthenticationRequest.Method == "SSO"
              && subItem.AuthenticationRequest.SignInURL.Length>1280)
                return APIHelper.GetErrorMessageByCode(51396);
            if (subItem != null
              && subItem.AuthenticationRequest != null
              && !string.IsNullOrEmpty(subItem.AuthenticationRequest.Method)
              && subItem.AuthenticationRequest.Method == "customVariable"
              && subItem.AuthenticationRequest.CustomVariable.Length>128)
                return APIHelper.GetErrorMessageByCode(51397);
            if (subItem != null
              && subItem.LocationRequest != null
              && string.IsNullOrEmpty(subItem.LocationRequest.ButtonText))
                return APIHelper.GetErrorMessageByCode(51398);
            if (subItem != null
              && subItem.LocationRequest != null
              && string.IsNullOrEmpty(subItem.LocationRequest.Message))
                return APIHelper.GetErrorMessageByCode(51399);
            if (subItem != null
              && subItem.LocationRequest != null
              && subItem.LocationRequest.ButtonText.Length>1024)
                return APIHelper.GetErrorMessageByCode(51400);
            if (subItem != null
              && subItem.LocationRequest != null
              && subItem.LocationRequest.Message.Length>1024)
                return APIHelper.GetErrorMessageByCode(51401);

            var quickResponses = subItem.Responses.Where(w => w.Type == EnumAnswerType.quickReply.ToString());
            if (quickResponses != null && quickResponses.Count() > 1)
                return APIHelper.GetErrorMessageByCode(51323);

            //if (quickResponses != null && quickResponses.Count() == 1)
            //{
            //    Response quickResponse = quickResponses.FirstOrDefault();
            //    subItem.Responses.Remove(quickResponse);
            //    subItem.Responses.Add(quickResponse);
            //}

            if (subItem.Channel == "default")
            {
                List<string> defautlChannelOnlySupportTypes = new List<string> {
                    "text","button","quickReply"
                }; 
                if (subItem.Responses.Any(f=> !defautlChannelOnlySupportTypes.Contains(f.Type)))
                {
                    return APIHelper.GetErrorMessageByCode(51351);
                }
            }

            if (isSupportComplex)
            {
                var complexResponses = subItem.Responses.Where(w => w.Type == EnumAnswerType.complex.ToString());
                if (complexResponses != null && complexResponses.Count() > 1)
                    return APIHelper.GetErrorMessageByCode(51345);
            }

            if (subItem != null && subItem.Responses != null && subItem.Responses.Count > 0)
            {
                foreach (var item in subItem.Responses)
                {
                    ErrorInfo error = ResponseValidation(item, subItem.Channel, botId, siteId, isSupportComplex);
                    if (error != null) return error;
                }
            }
            return null;
        }
        private ErrorInfo ResponseValidation(ResponseCreateDto response,string channelType, Guid botId, int siteId, bool isSupportComplex = false)
        {
            if (channelType == "default")
            {
                if (response.Type != "text"
                    && response.Type != "button"
                    && response.Type != "quickReply")
                {
                    return APIHelper.GetErrorMessageByCode(51351);
                }
            }
            
            switch (response.Type)
            {
                case "text":
                    if (response.TextVariants == null || response.TextVariants.Count <= 0)
                        return APIHelper.GetErrorMessageByCode(51221);
                    else if (response.TextVariants.Count > 10)
                        return APIHelper.GetErrorMessageByCode(51222);
                    //string totalText = string.Join(CommonCharacter.Split, textResponse.texts);
                    //if (totalText.Length > 4000)
                    //    return APIHelper.GetErrorMessageByCode(51364);
                    else if (response.TextVariants.Any(a => string.IsNullOrWhiteSpace(a)))
                        return APIHelper.GetErrorMessageByCode(51223);
                    //if (channel != ConstChannelType.Livechat)
                    //{
                    //    if (textResponse.texts.Any(a => a.Contains("href=\"intent") || a.Contains("href='intent") || a.Contains("data-intent")))
                    //        return APIHelper.GetErrorMessageByCode(51363);
                    //}
                    break;
                case "image":
                    if (response.Image == null)
                        return APIHelper.GetErrorMessageByCode(51224);
                    if (string.IsNullOrWhiteSpace(response.Image.Name))
                        return APIHelper.GetErrorMessageByCode(51225);
                    if (response.Image.Id == Guid.Empty)
                        return APIHelper.GetErrorMessageByCode(51226);
                    if (response.Image.Name.Length > 128)
                        return APIHelper.GetErrorMessageByCode(51227);
                    //if (response.Image.url.Length > 1280)
                    //    return APIHelper.GetErrorMessageByCode(51228);
                    break;
                case "video":

                    if (string.IsNullOrWhiteSpace(response.VideoUrl))
                        return APIHelper.GetErrorMessageByCode(51229);
                    //if (string.IsNullOrWhiteSpace(videoResponse.url))
                    //    return APIHelper.GetErrorMessageByCode(51230);
                    if (response.VideoUrl.Length > 512)
                        return APIHelper.GetErrorMessageByCode(51231);
                    break;
                case "webhook":

                    if (response.Webhook == null)
                        return APIHelper.GetErrorMessageByCode(51232);
                    if (string.IsNullOrWhiteSpace(response.Webhook.URL))
                        return APIHelper.GetErrorMessageByCode(51233);
                    if (response.Webhook.URL.Length > 1280)
                        return APIHelper.GetErrorMessageByCode(51234);
                    if (response.Webhook.Headers != null && response.Webhook.Headers.Count > 0)
                    {
                        if (response.Webhook.Headers.Any(a => string.IsNullOrWhiteSpace(a.Key)))
                        {
                            return APIHelper.GetErrorMessageByCode(51381);
                        }
                        if (response.Webhook.Headers.Any(a => !string.IsNullOrWhiteSpace(a.Key) && a.Key.Length > 4000))
                        {
                            return APIHelper.GetErrorMessageByCode(51384);
                        }
                        if (response.Webhook.Headers.Any(a => string.IsNullOrWhiteSpace(a.Value)))
                        {
                            return APIHelper.GetErrorMessageByCode(51382);
                        }
                        if (response.Webhook.Headers.Any(a => !string.IsNullOrWhiteSpace(a.Value) && a.Value.Length > 4000))
                        {
                            return APIHelper.GetErrorMessageByCode(51385);
                        }
                    }

                    break;
                case "quickReply":
        
                    if (response.QuickReply == null)
                    {
                        //if (jObj == null || !jObj.TryGetValue("quickReplyId", out jtId) || jtId == null)
                        //{
                        //    return APIHelper.GetErrorMessageByCode(51235);
                        //}
                        //string pattern = "^[0-9]*$";
                        //if (!Regex.IsMatch(jtId.ToString(), pattern))
                        //{
                        //    return APIHelper.GetErrorMessageByCode(51358);
                        //}
                        return APIHelper.GetErrorMessageByCode(51235);
                    }
                    //2019.7.16 允许为空
                    //if (string.IsNullOrWhiteSpace(quickReplyResponse.text))
                    //    return APIHelper.GetErrorMessageByCode(51236);
                    if (!string.IsNullOrWhiteSpace(response.Message)
                        && response.Message.Length > 1024)
                        return APIHelper.GetErrorMessageByCode(51402);
                    if (!string.IsNullOrWhiteSpace(response.QuickReply.Name)
                            && response.QuickReply.Name.Length > 128)
                        return APIHelper.GetErrorMessageByCode(51237);
                    //codereview by davy: 这里QuickReply.Id为空 不应该报错
                    //正确逻辑是 没有Id 就是新增， 有Id 就是 更新
                    if (response.QuickReply.Id == Guid.Empty)
                        return APIHelper.GetErrorMessageByCode(51238);
                    var quickReply = _quickReplyDomainService.Get(response.QuickReply.Id);
                    if (quickReply == null)
                        return APIHelper.GetErrorMessageByCode(51324, new object[] { response.QuickReply.Id });
                    //if (quickReply.SiteId != siteId)
                    //    return APIHelper.GetErrorMessageByCode(51325, new object[] { quickReplyResponse.quickReplyId, siteId });
                    if (botId != Guid.Empty && quickReply.BotId != botId)
                        return APIHelper.GetErrorMessageByCode(51326, new object[] { response.QuickReply.Id, botId });
                    break;
                case "button":
                    List<string> buttonTypes = new List<string> {
                        "triggerAnIntent","link","webView"
                    };
                    List<string> openInTypes = Enum.GetNames(typeof(EnumOpenIn)).ToList();
                    List<string> openStyleTypes = Enum.GetNames(typeof(EnumOpenStyle)).ToList();

                    if (response.Buttons == null || response.Buttons.Count<=0)
                        return APIHelper.GetErrorMessageByCode(51239);
                    if(response.Buttons.Any(f=> !buttonTypes.Contains(f.Type) ))
                        return APIHelper.GetErrorMessageByCode(51246);
                    if (response.Buttons.Any(f => f.Type == "triggerAnIntent"&& f.IntentId == Guid.Empty))
                        return APIHelper.GetErrorMessageByCode(51249);
                    //if (response.Buttons.Any(f => !string.IsNullOrWhiteSpace(f.IntentId) && !Guid.TryParse(f.IntentId, out var result)))
                    //    return APIHelper.GetErrorMessageByCode(51359);
                    if (response.Buttons.Any(f => !string.IsNullOrWhiteSpace(f.OpenIn) && !openInTypes.Contains(f.OpenIn)))
                        return APIHelper.GetErrorMessageByCode(51244);
                    if (response.Buttons.Any(f => !string.IsNullOrWhiteSpace(f.OpenStyle) && !openStyleTypes.Contains(f.OpenStyle)))
                        return APIHelper.GetErrorMessageByCode(51245);
                    if (!string.IsNullOrWhiteSpace(response.Message)
                        && response.Message.Length > 1024)
                        return APIHelper.GetErrorMessageByCode(51402);
                    if (response.Buttons.Any(f => string.IsNullOrWhiteSpace(f.Text)))
                        return APIHelper.GetErrorMessageByCode(51245);
                    if (response.Buttons.Any(f => f.Text.Length>128))
                        return APIHelper.GetErrorMessageByCode(51377);
                    if (response.Buttons.Any(f => (f.Type == "link" || f.Type == "webView") && string.IsNullOrWhiteSpace(f.Url)))
                        return APIHelper.GetErrorMessageByCode(51252);
                    if (response.Buttons.Any(f => (f.Type == "link" || f.Type == "webView") && f.Url.Length > 512))
                        return APIHelper.GetErrorMessageByCode(51253);

                    var buttonWhenGoToIntents = response.Buttons.Where(f => f.Type == "triggerAnIntent");
                    if (buttonWhenGoToIntents != null&& buttonWhenGoToIntents.Count()>0)
                    {
                        foreach(var button in buttonWhenGoToIntents)
                        {
                            var intent = _intentDomainService.Get(button.IntentId);
                            if (intent == null)
                                return APIHelper.GetErrorMessageByCode(51310, new object[] { button.IntentId });                  
                        }                       
                    }

                    break;
                case "complex":
                    if (isSupportComplex)
                    {
                        if (channelType != "livechat")
                        {
                            return APIHelper.GetErrorMessageByCode(51352);
                        }
 
                        if (string.IsNullOrWhiteSpace(response.Message))
                            return APIHelper.GetErrorMessageByCode(51343);
                    }
                    else
                    {
                        return APIHelper.GetErrorMessageByCode(51344);
                    }
                    break;                
            }
            return null;
        }
    }
    public interface ICategoryVerifyDataManager
    {
        ErrorInfo VerifyGet(Guid id);
        ErrorInfo VerifyCreate(Guid botId, Dto.CategoryCreateDto categoryCreateDto);
        ErrorInfo VerifyUpdate(Guid id, Dto.CategoryUpdateDto categoryUpdateDto);
        ErrorInfo VerifyDelete(Guid id);
        ErrorInfo VerifyReassign(Guid id, Guid targetCategoryId);
        ErrorInfo VerifyGetList(Guid botId);
    }
    public class CategoryVerifyDataManager : ICategoryVerifyDataManager
    {
        private readonly IChatbotDomainService _chatbotDomainService;
        private readonly ICategoryDomainService _categoryDomainService;
        public CategoryVerifyDataManager(IChatbotDomainService chatbotDomainService,
            ICategoryDomainService categoryDomainService)
        {
            _chatbotDomainService = chatbotDomainService;
            _categoryDomainService = categoryDomainService;
        }

        public ErrorInfo VerifyCreate(Guid botId, Dto.CategoryCreateDto categoryCreateDto)
        {
            ErrorInfo errorInfo = new ErrorInfo { Code = 1 };
            var bot = _chatbotDomainService.Get(botId);
            if (bot == null || bot.Id == Guid.Empty)
            {
                return APIHelper.GetErrorMessageByCode(50004);
            }

            if (bot.EngineType == EnumBotType.thirdPartyBot)
            {
                return APIHelper.GetErrorMessageByCode(50264);
            }

            if (categoryCreateDto!=null
                && categoryCreateDto.ParentId.HasValue
                && categoryCreateDto.ParentId != Guid.Empty)
            {
                var catagoryParent = _categoryDomainService.Get(categoryCreateDto.ParentId.Value);
                if (catagoryParent == null || catagoryParent.IsDeleted)
                {
                    return APIHelper.GetErrorMessageByCode(50220);
                }

                if (botId != Guid.Empty && catagoryParent.BotId != botId)
                {
                    return APIHelper.GetErrorMessageByCode(50254);
                }                    
            }

            if (_categoryDomainService.GetByBotId(botId).Exists(f=>f.Name == categoryCreateDto.Name.Trim()))
            {
                return APIHelper.GetErrorMessageByCode(50215);
            }               

            return errorInfo;
        }

        public ErrorInfo VerifyDelete(Guid id)
        {
            ErrorInfo errorInfo = new ErrorInfo { Code = 1 };

            var category = _categoryDomainService.Get(id);
            if (category == null || category.IsDeleted)
            {
                errorInfo = APIHelper.GetErrorMessageByCode(50004);
            }

            return errorInfo;
        }

        public ErrorInfo VerifyGet(Guid id)
        {
            ErrorInfo errorInfo = new ErrorInfo { Code = 1 };
            var category = _categoryDomainService.Get(id);
            if (category == null || category.IsDeleted)
            {
                errorInfo = APIHelper.GetErrorMessageByCode(50004);
            }
            return errorInfo;
        }

        public ErrorInfo VerifyUpdate(Guid id, Dto.CategoryUpdateDto categoryUpdateDto)
        {
            ErrorInfo errorInfo = new ErrorInfo { Code = 1 };
            var category = _categoryDomainService.Get(id);
            if (category == null || category.IsDeleted)
            {
                errorInfo = APIHelper.GetErrorMessageByCode(50004);
            }
            
            if (categoryUpdateDto.ParentId.HasValue
                && categoryUpdateDto.ParentId != Guid.Empty)
            {
                var categoryParent = _categoryDomainService.Get(categoryUpdateDto.ParentId.Value);
                if (categoryParent == null || categoryParent.IsDeleted)
                {
                    return APIHelper.GetErrorMessageByCode(50220);
                }

                if (categoryParent.BotId != category.BotId)
                {
                    return APIHelper.GetErrorMessageByCode(50254);
                }
            }

            if (_categoryDomainService.GetByBotId(category.BotId).Exists(f=>f.Id!=id&&f.Name == categoryUpdateDto.Name.Trim()))
            {
                return APIHelper.GetErrorMessageByCode(50215);
            }

            return errorInfo;
        }

        public ErrorInfo VerifyReassign(Guid id, Guid targetCategoryId)
        {
            ErrorInfo errorInfo = new ErrorInfo { Code = 1 };
            var category = _categoryDomainService.Get(id);
            if (category == null || category.IsDeleted)
            {
                errorInfo = APIHelper.GetErrorMessageByCode(50004);
            }

            var bot = _chatbotDomainService.Get(category.BotId);
            if (bot == null || bot.Id == Guid.Empty)
            {
                return APIHelper.GetErrorMessageByCode(50004);
            }

            if (bot.EngineType == EnumBotType.thirdPartyBot)
            {
                return APIHelper.GetErrorMessageByCode(50264);
            }

            var targetCategory = _categoryDomainService.Get(targetCategoryId);
            if (targetCategory == null || targetCategory.IsDeleted)
            {
                return APIHelper.GetErrorMessageByCode(50220);
            }

            if (targetCategory.BotId != category.BotId)
            {
                return APIHelper.GetErrorMessageByCode(50254);
            }

            return errorInfo;
        }

        public ErrorInfo VerifyGetList(Guid botId)
        {
            ErrorInfo errorInfo = new ErrorInfo { Code = 1 };
            var category = _chatbotDomainService.Get(botId);
            if (category == null || category.IsDeleted)
            {
                errorInfo = APIHelper.GetErrorMessageByCode(50004);
            }
            return errorInfo;
        }
    }
}
